/*
	           MICRO-MENU

	     (C) Dean Camera, 2007
	    www.fourwalledcubicle.com
	dean_camera@fourwalledcubicle.com
	
	    Royalty-free for all uses.
	                                  */

#ifndef MENU_H
#define MENU_H

#include <avr/pgmspace.h>

#define FIRMWARE "Firmware ver: 4.0b"
#define temp_treshold 5500
#define colib_max_temp 4800
#define recolib_temp_treshold 4700

// Typedefs:
typedef void (*FuncPtr)(void);
typedef void (*WriteFuncPtr)(const char*);

typedef struct PROGMEM{
	void       *Next;
	void       *Previous;
	void       *Parent;
	void       *Sibling;
	FuncPtr     SelectFunc;
	FuncPtr     EnterFunc;	
	unsigned short 	   *ADC_numb;
	const char  Text_units[6];
	const char  Text[];
} Menu_Item ;

struct str_ADC_data {
unsigned short PWR_laser;
unsigned short PLT_current;
unsigned short Laser_current;
unsigned short Temp;
unsigned short OP_point;
 short Nu_error;
 short Nu_range;
 short contrast_range;
unsigned char filter;
};

struct {
unsigned short B;
//unsigned short P;
//unsigned short I;
//unsigned short D;
unsigned short power_laser;
unsigned short R25;
}str_Settings;


volatile struct str_ADC_data ADC_data;
volatile struct str_ADC_data DAC_data;


// Externs:
extern WriteFuncPtr*    WriteFunc;
extern Menu_Item        Null_Menu;
extern Menu_Item*       CurrMenuItem;

// Defines and Macros:
#define NULL_ENTRY Null_Menu
#define NULL_FUNC  (void*)0
#define NULL_TEXT  0x00


#define PREVIOUS   ((Menu_Item*)pgm_read_word(&CurrMenuItem->Previous))
#define NEXT       ((Menu_Item*)pgm_read_word(&CurrMenuItem->Next))
#define PARENT     ((Menu_Item*)pgm_read_word(&CurrMenuItem->Parent))
#define SIBLING    ((Menu_Item*)pgm_read_word(&CurrMenuItem->Sibling))
#define ENTERFUNC  ((FuncPtr*)pgm_read_word(&CurrMenuItem->EnterFunc))
#define SELECTFUNC ((FuncPtr*)pgm_read_word(&CurrMenuItem->SelectFunc))
#define SHOW_ADC_NUMB ((unsigned short*)pgm_read_word(&CurrMenuItem->ADC_numb))

#define MAKE_MENU(Name, Next, Previous, Parent, Sibling, SelectFunc, EnterFunc,	ADC_numb,Text_units, ...) \
    extern Menu_Item Next;     \
	extern Menu_Item Previous; \
	extern Menu_Item Parent;   \
	extern Menu_Item Sibling;  \
	Menu_Item Name = {(void*)&Next, (void*)&Previous, (void*)&Parent, (void*)&Sibling, (FuncPtr)SelectFunc, (FuncPtr)EnterFunc,(unsigned short*)&ADC_numb,{Text_units},{__VA_ARGS__}}

#define SET_MENU_WRITE_FUNC(x) \
	WriteFunc = (WriteFuncPtr*)x;

#define SET_MENU(x) \
	MenuChange((Menu_Item*)x);
	
#define GO_MENU_FUNC(x)  \
	MenuFunc((FuncPtr*)x)
	
#define EXTERN_MENU(Name) \
    extern Menu_Item Name;

#define SET_LASER_CURRENT	0
#define SET_PLT_CURRENT		1
#define SET_FILTER			2

// Prototypes:
void MenuChange(Menu_Item* NewMenu);
void MenuFunc(FuncPtr* Function);
void MenuInit (void);
void show_menu_on_LCD(void);
void show_ADC_on_LCD (void);

void menu_Laser_current_select (void);
void menu_PLT_current_select (void);
void menu_Filters_select (void);
void menu_write_eeprom (void);
void menu_setting_B (void);
void menu_setting_pwr (void);
void menu_setting_R25 (void);
unsigned char* enter_number_frm_keyboard (unsigned char ,unsigned char );

void set_dac_data (unsigned short , unsigned char );
void Init_pilte(void);
void read_adcs(void);
unsigned char* short_to_mass (unsigned short *,unsigned,unsigned,unsigned,unsigned);
unsigned short mass_to_short (unsigned char *,unsigned,unsigned,unsigned,unsigned);
void EEPROM_write (unsigned int , unsigned char );
unsigned char EEPROM_read (unsigned int );
void menu_read_eeprom (void);
void menu_clear_eeprom (void);
#endif
